package com.swak.vertx.protocol.http.adapter;

import java.util.concurrent.CompletionStage;

import com.swak.exception.BlockException;
import com.swak.vertx.invoker.ForbidBlockCompletableFuture;
import com.swak.vertx.invoker.MethodInvoker;

import io.vertx.ext.web.RoutingContext;

/**
 * 处理 CTX
 * 
 * @author lifeng
 */
public interface Adapter {


	/**
	 * 处理请求
	 * 
	 * @param context
	 * @param handler
	 * @return
	 */
	CompletionStage<Context> handle(Context context);

	/**
	 * 下一个处理器
	 * 
	 * @param next
	 * @return
	 */
	Adapter chain(Adapter next);

	/**
	 * 执行的上下文
	 * 
	 * @author DELL
	 */
	public static class Context extends ForbidBlockCompletableFuture<Context> {

		public static Context of(RoutingContext $context, MethodInvoker $method) {
			return new Context($context, $method);
		}

		final RoutingContext $context;
		final MethodInvoker $method;
		Throwable $error;
		Object $result;
		Object $metric;

		public RoutingContext getContext() {
			return $context;
		}

		public Throwable getError() {
			return $error;
		}

		private Context(RoutingContext $context, MethodInvoker $method) {
			this.$context = $context;
			this.$method = $method;
		}

		@Override
		public boolean complete(Context value) {
			throw new BlockException("Context 调用栈中不能调用 complete(), 执行链结束后会自动调用  $complete！");
		}

		@Override
		public boolean completeExceptionally(Throwable ex) {
			throw new BlockException("Context 调用栈中不能调用 completeExceptionally(), 执行链结束后会自动调用  $complete！");
		}

		/**
		 * 完成: 
		 * 
		 * @param error
		 */
		public void $complete(Throwable error) {
			this.$error = error;
			super.complete(this);
		}
	}
}